{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from PyPDF2 import PdfFileReader as reader, PdfFileWriter as writer\n",
    "from PyPDF2.generic import Destination"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_bookmark(page):\n",
    "  return (str(page['/Title']).strip().strip(b'\\x00'.decode()), input.getDestinationPageNumber(page))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "input = reader('./pdf/input.pdf')\n",
    "outlines = input.getOutlines()\n",
    "bookmarks = []\n",
    "for page in outlines:\n",
    "  if isinstance(page, Destination):\n",
    "    bookmarks.append(get_bookmark(page))\n",
    "  elif isinstance(page, list):\n",
    "    for sub_page in page:\n",
    "      if isinstance(sub_page, Destination):\n",
    "        bookmarks.append(get_bookmark(sub_page))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "input = reader('./pdf/output.pdf')\n",
    "output = writer()\n",
    "output.cloneDocumentFromReader(input)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "封面 0\n",
      "书名 2\n",
      "版权 3\n",
      "前言 4\n",
      "目录 23\n",
      "1——第 0 章：准备工作 30\n",
      "2 31\n",
      "3 32\n",
      "4 33\n",
      "5 34\n",
      "6 35\n",
      "7 36\n",
      "8 37\n",
      "9 38\n",
      "10 39\n",
      "11 40\n",
      "12 41\n",
      "13 42\n",
      "14 43\n",
      "15——第一章：python 对象初探 44\n",
      "16 45\n",
      "17 46\n",
      "18 47\n",
      "19 48\n",
      "20 49\n",
      "21 50\n",
      "22 51\n",
      "23 52\n",
      "24 53\n",
      "25 54\n",
      "26 55\n",
      "27 56\n",
      "28 57\n",
      "29——第二章：python 中的整数对象 58\n",
      "30 59\n",
      "31 60\n",
      "32 61\n",
      "33 62\n",
      "34 63\n",
      "35 64\n",
      "36 65\n",
      "37 66\n",
      "38 67\n",
      "39 68\n",
      "40 69\n",
      "41 70\n",
      "42 71\n",
      "43 72\n",
      "44 73\n",
      "45 74\n",
      "46 75\n",
      "47——第三章：python 中的字符串对象 76\n",
      "48 77\n",
      "49 78\n",
      "50 79\n",
      "51 80\n",
      "52 81\n",
      "53 82\n",
      "54 83\n",
      "55 84\n",
      "56 85\n",
      "57 86\n",
      "58 87\n",
      "59 88\n",
      "60 89\n",
      "61 90\n",
      "62 91\n",
      "63—— 第 4 章：python 中的 List 对象 92\n",
      "64 93\n",
      "65 94\n",
      "66 95\n",
      "67 96\n",
      "68 97\n",
      "69 98\n",
      "70 99\n",
      "71 100\n",
      "72 101\n",
      "73 102\n",
      "74 103\n",
      "75 104\n",
      "76 105\n",
      "77——第 5 章：Python 中的 Dict 对象 106\n",
      "78 107\n",
      "79 108\n",
      "80 109\n",
      "81 110\n",
      "82 111\n",
      "83 112\n",
      "84 113\n",
      "85 114\n",
      "86 115\n",
      "87 116\n",
      "88 117\n",
      "89 118\n",
      "90 119\n",
      "91 120\n",
      "92 121\n",
      "93 122\n",
      "94 123\n",
      "95 124\n",
      "96 125\n",
      "97 126\n",
      "98 127\n",
      "99 128\n",
      "100 129\n",
      "101——第 6 章：最简单的 python 模拟 130\n",
      "102 131\n",
      "103 132\n",
      "104 133\n",
      "105 134\n",
      "106 135\n",
      "107 136\n",
      "108 137\n",
      "109 138\n",
      "110 139\n",
      "111 140\n",
      "112 141\n",
      "113——第 7 章：python 的编译结果:code 对象与 pyc 文件 142\n",
      "114 143\n",
      "115 144\n",
      "116 145\n",
      "117 146\n",
      "118 147\n",
      "119 148\n",
      "120 149\n",
      "121 150\n",
      "122 151\n",
      "123 152\n",
      "124 153\n",
      "125 154\n",
      "126 155\n",
      "127 156\n",
      "128 157\n",
      "129 158\n",
      "130 159\n",
      "131 160\n",
      "132 161\n",
      "133——第 8 章：python 虚拟机框架 162\n",
      "134 163\n",
      "135 164\n",
      "136 165\n",
      "137 166\n",
      "138 167\n",
      "139 168\n",
      "140 169\n",
      "141 170\n",
      "142 171\n",
      "143 172\n",
      "144 173\n",
      "145 174\n",
      "146 175\n",
      "147 176\n",
      "148 177\n",
      "149 178\n",
      "150 179\n",
      "151 180\n",
      "152 181\n",
      "153 182\n",
      "154 183\n",
      "155 184\n",
      "156 185\n",
      "157——第 9 章：python 虚拟机中的一般表达式 186\n",
      "158 187\n",
      "159 188\n",
      "160 189\n",
      "161 190\n",
      "162 191\n",
      "163 192\n",
      "164 193\n",
      "165 194\n",
      "166 195\n",
      "167 196\n",
      "168 197\n",
      "169 198\n",
      "170 199\n",
      "171 200\n",
      "172 201\n",
      "173——第 10 章：python 虚拟机中的控制流 202\n",
      "174 203\n",
      "175 204\n",
      "176 205\n",
      "177 206\n",
      "178 207\n",
      "179 208\n",
      "180 209\n",
      "181 210\n",
      "182 211\n",
      "183 212\n",
      "184 213\n",
      "185 214\n",
      "186 215\n",
      "187 216\n",
      "188 217\n",
      "189 218\n",
      "190 219\n",
      "191 220\n",
      "192 221\n",
      "193 222\n",
      "194 223\n",
      "195 224\n",
      "196 225\n",
      "197 226\n",
      "198 227\n",
      "199 228\n",
      "200 229\n",
      "201 230\n",
      "202 231\n",
      "203 232\n",
      "204 233\n",
      "205 234\n",
      "206 235\n",
      "207 236\n",
      "208 237\n",
      "209 238\n",
      "210 239\n",
      "211 240\n",
      "212 241\n",
      "213 242\n",
      "214 243\n",
      "215——第 11 章：python 虚拟机中的函数机制 244\n",
      "216 245\n",
      "217 246\n",
      "218 247\n",
      "219 248\n",
      "220 249\n",
      "221 250\n",
      "222 251\n",
      "223 252\n",
      "224 253\n",
      "225 254\n",
      "226 255\n",
      "227 256\n",
      "228 257\n",
      "229 258\n",
      "230 259\n",
      "231 260\n",
      "232 261\n",
      "233 262\n",
      "234 263\n",
      "235 264\n",
      "236 265\n",
      "237 266\n",
      "238 267\n",
      "239 268\n",
      "240 269\n",
      "241 270\n",
      "242 271\n",
      "243 272\n",
      "244 273\n",
      "245 274\n",
      "246 275\n",
      "247 276\n",
      "248 277\n",
      "249 278\n",
      "250 279\n",
      "251 280\n",
      "252 281\n",
      "253 282\n",
      "254 283\n",
      "255 284\n",
      "256 285\n",
      "257 286\n",
      "258 287\n",
      "259——第 12 章：python 虚拟机中的类机制 288\n",
      "260 289\n",
      "261 290\n",
      "262 291\n",
      "263 292\n",
      "264 293\n",
      "265 294\n",
      "266 295\n",
      "267 296\n",
      "268 297\n",
      "269 298\n",
      "270 299\n",
      "271 300\n",
      "272 301\n",
      "273 302\n",
      "274 303\n",
      "275 304\n",
      "276 305\n",
      "277 306\n",
      "278 307\n",
      "279 308\n",
      "280 309\n",
      "281 310\n",
      "282 311\n",
      "283 312\n",
      "284 313\n",
      "285 314\n",
      "286 315\n",
      "287 316\n",
      "288 317\n",
      "289 318\n",
      "290 319\n",
      "291 320\n",
      "292 321\n",
      "293 322\n",
      "294 323\n",
      "295 324\n",
      "296 325\n",
      "297 326\n",
      "298 327\n",
      "299 328\n",
      "300 329\n",
      "301 330\n",
      "302 331\n",
      "303 332\n",
      "304 333\n",
      "305 334\n",
      "306 335\n",
      "307 336\n",
      "308 337\n",
      "309 338\n",
      "310 339\n",
      "311 340\n",
      "312 341\n",
      "313 342\n",
      "314 343\n",
      "315——第 13 章：python 运行环境初始化 344\n",
      "316 345\n",
      "317 346\n",
      "318 347\n",
      "319 348\n",
      "320 349\n",
      "321 350\n",
      "322 351\n",
      "323 352\n",
      "324 353\n",
      "325 354\n",
      "326 355\n",
      "327 356\n",
      "328 357\n",
      "329 358\n",
      "330 359\n",
      "331 360\n",
      "332 361\n",
      "333 362\n",
      "334 363\n",
      "335 364\n",
      "336 365\n",
      "337 366\n",
      "338 367\n",
      "339 368\n",
      "340 369\n",
      "341 370\n",
      "342 371\n",
      "343——第 14 章：python 模块的动态加载机制 372\n",
      "344 373\n",
      "345 374\n",
      "346 375\n",
      "347 376\n",
      "348 377\n",
      "349 378\n",
      "350 379\n",
      "351 380\n",
      "352 381\n",
      "353 382\n",
      "354 383\n",
      "355 384\n",
      "356 385\n",
      "357 386\n",
      "358 387\n",
      "359 388\n",
      "360 389\n",
      "361 390\n",
      "362 391\n",
      "363 392\n",
      "364 393\n",
      "365 394\n",
      "366 395\n",
      "367 396\n",
      "368 397\n",
      "369 398\n",
      "370 399\n",
      "371 400\n",
      "372 401\n",
      "373 402\n",
      "374 403\n",
      "375 404\n",
      "376 405\n",
      "377 406\n",
      "378 407\n",
      "379 408\n",
      "380 409\n",
      "381 410\n",
      "382 411\n",
      "383 412\n",
      "384 413\n",
      "385 414\n",
      "386 415\n",
      "387 416\n",
      "388 417\n",
      "389 418\n",
      "390 419\n",
      "391——第 15 章：python 多线程机制 420\n",
      "392 421\n",
      "393 422\n",
      "394 423\n",
      "395 424\n",
      "396 425\n",
      "397 426\n",
      "398 427\n",
      "399 428\n",
      "400 429\n",
      "401 430\n",
      "402 431\n",
      "403 432\n",
      "404 433\n",
      "405 434\n",
      "406 435\n",
      "407 436\n",
      "408 437\n",
      "409 438\n",
      "410 439\n",
      "411 440\n",
      "412 441\n",
      "413 442\n",
      "414 443\n",
      "415 444\n",
      "416 445\n",
      "417 446\n",
      "418 447\n",
      "419 448\n",
      "420 449\n",
      "421 450\n",
      "422 451\n",
      "423 452\n",
      "424 453\n",
      "425 454\n",
      "426 455\n",
      "427 456\n",
      "428 457\n",
      "429——第 16 章：python 的内存管理机制 458\n",
      "430 459\n",
      "431 460\n",
      "432 461\n",
      "433 462\n",
      "434 463\n",
      "435 464\n",
      "436 465\n",
      "437 466\n",
      "438 467\n",
      "439 468\n",
      "440 469\n",
      "441 470\n",
      "442 471\n",
      "443 472\n",
      "444 473\n",
      "445 474\n",
      "446 475\n",
      "447 476\n",
      "448 477\n",
      "449 478\n",
      "450 479\n",
      "451 480\n",
      "452 481\n",
      "453 482\n",
      "454 483\n",
      "455 484\n",
      "456 485\n",
      "457 486\n",
      "458 487\n",
      "459 488\n",
      "460 489\n",
      "461 490\n",
      "462 491\n",
      "463 492\n",
      "464 493\n",
      "465 494\n",
      "466 495\n",
      "467 496\n",
      "468 497\n",
      "469 498\n",
      "470 499\n",
      "471 500\n",
      "472 501\n",
      "473 502\n",
      "474 503\n",
      "475 504\n",
      "476 505\n",
      "477 506\n",
      "478 507\n",
      "479 508\n",
      "480 509\n"
     ]
    }
   ],
   "source": [
    "for title, page_num in bookmarks:\n",
    "  print(title, page_num)\n",
    "  output.addBookmark(title, page_num)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('./pdf/output_bookmark.pdf', 'wb') as f:\n",
    "  output.write(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "c8021be2121acb6aedb321c9fc0970845e72ecff144800146fabd90eee2b1d5e"
  },
  "kernelspec": {
   "display_name": "Python 3.8.12 64-bit ('learn': conda)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.12"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
